package com.titaniume.rabbitmq.springbootrabbitmq.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @ProjectName: rabbitmq
 * @Package: com.titaniume.rabbitmq.springbootrabbitmq.config
 * @ClassName: MyCallBack
 * @Author: titan
 * @Description: 回调接口
 * @Date: 2022/1/3 16:39
 * @Version: 1.0
 */
@Slf4j
@Component
public class MyCallBack implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnsCallback {



    @Autowired
    private  RabbitTemplate rabbitTemplate;

    //注入
    @PostConstruct
    public  void init(){
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnsCallback(this);
        /**
         * Mandatory为true时,消息通过交换器无法匹配到队列会返回给生产者
         *  为false时,匹配不到会直接被丢弃
         */
        rabbitTemplate.setMandatory(true);
    }





    /**
     * 交换机回调方法
     * 1.发消息 交换机收到了 回调
     *  1.1 correlationData 保存回调消息的ID相关信息
     *  1.2 交换机收到消息 ack = true
     *  1.3 cause null
     *
     *  2发消息 交换机接收失败了 回调
     *   2.1 correlationData 保存回调消息的ID相关信息
     *   2.2 交换机收到消息 ack = false
     *   2.3 cause 失败的原因
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause ) {
        String id = correlationData!=null ? correlationData.getId() : "";
        if (ack){
            log.info("交换机收到ID为:{} 的消息",id);
        }else {
            log.info("交换机还未收到ID为:{} 的消息,原因为:{}",id,cause);
        }
    }

    //可以在当消息传递过程中不可达目的得的时候将消息返回给生产者
    //只有不可达目的的时候 才会回退
    @Override
    public void returnedMessage(ReturnedMessage returned) {
        log.info("消息{},被交换机{} 退回,退回原因:{},路由Key:{}",new String(returned.getMessage().getBody()),returned.getExchange(),returned.getReplyText(),returned.getRoutingKey());
    }
}
